package com.dt.platform.oa.service.impl;

import com.dt.platform.domain.oa.NetdiskOriginFile;
import com.dt.platform.oa.service.INetdiskStoreDataService;
import com.github.foxnic.commons.encrypt.MD5Util;
import com.github.foxnic.commons.log.Logger;
import io.minio.*;
import io.minio.errors.*;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.text.SimpleDateFormat;
import java.util.Date;


@Service("NetdiskStoreDataMinioServiceImpl")
public class NetdiskStoreDataMinioServiceImpl implements INetdiskStoreDataService{

    public String storageType="minio";

    @Value("${foxnic.storage.minio.endpoint}")
    private String endpoint;

    @Value("${foxnic.storage.minio.accessKey}")
    private String accessKey;

    @Value("${foxnic.storage.minio.secretKey}")
    private String secretKey;

    @Value("${foxnic.storage.minio.bucketNetdisk}")
    private String bucket;

    @Override
    public String getStorageType(){

        return storageType;
    }


    @Override
    public boolean removeFile(NetdiskOriginFile fileInfo) {
        return true;
    }

    public MinioClient getMinioClient() {
        Logger.info("endpoint:"+  endpoint+",accessKey:"+  accessKey + ",secretKey:"+  secretKey);
        return MinioClient.builder().endpoint(endpoint).credentials(accessKey, secretKey).build();
    }
    private String getFileName(String filename){
        SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd");
        // 设置存储对象名称
        String dir = sdf.format(new Date());
        int idx = filename.lastIndexOf(".");
        if (idx >= 0) {
            String ext = filename.substring(idx+1);
            String name = System.currentTimeMillis() + filename.substring(0, idx);
            filename = MD5Util.encrypt32(name) + "." + ext;
        }else{
            String name = System.currentTimeMillis() + filename;
            filename = MD5Util.encrypt32(name) + ".block";
        }
        return dir + "/" +filename;
    }
    @Override
    public Boolean write(NetdiskOriginFile fileInfo, MultipartFile file) {
        Boolean res=true;
        fileInfo.setStorageType(storageType);
        String filename = getFileName(file.getOriginalFilename());
        Logger.info("originalFilename:"+  file.getOriginalFilename());
        Logger.info("oss filename:"+  filename);
        Logger.info("fileSize:"+  file.getSize());
        Logger.info("bucket:"+  bucket);
        Logger.info("contentType:"+  file.getContentType());
        fileInfo.setLocation(filename);
        ObjectWriteResponse response;
        try {
            MinioClient client=getMinioClient();
            if(!client.bucketExists(BucketExistsArgs.builder().bucket(bucket).build())){
                client.makeBucket(MakeBucketArgs.builder().bucket(bucket).build());
            }
            response = client.putObject(PutObjectArgs.builder()
                    .bucket(bucket)
                    .object(filename)
                    .contentType(file.getContentType())
                    .stream(file.getInputStream(), file.getSize(), ObjectWriteArgs.MIN_MULTIPART_SIZE).build());
        } catch (ErrorResponseException e) {
            e.printStackTrace();
            res=false;
        } catch (InsufficientDataException e) {
            e.printStackTrace();
            res=false;
        } catch (InternalException e) {
            e.printStackTrace();
            res=false;
        } catch (InvalidKeyException e) {
            e.printStackTrace();
            res=false;
        } catch (InvalidResponseException e) {
            e.printStackTrace();
            res=false;
        } catch (IOException e) {
            e.printStackTrace();
            res=false;
        } catch (NoSuchAlgorithmException e) {
             e.printStackTrace();
            res=false;
        } catch (ServerException e) {
            e.printStackTrace();
            res=false;
        } catch (XmlParserException e) {
            e.printStackTrace();
            res=false;
        }
        Logger.info("oss write result:"+res);
        return res;
    }



    @Override
    public InputStream readStream(NetdiskOriginFile fileInfo) {
        MinioClient client=getMinioClient();
        InputStream stream=null;
        Boolean isFileExists=isFileExists(fileInfo);
        if(!isFileExists){
            return null;
        }
        try {
            stream=client.getObject(GetObjectArgs.builder().bucket(bucket).object(fileInfo.getLocation()).build());
        } catch (ErrorResponseException e) {
            e.printStackTrace();
        } catch (InsufficientDataException e) {
            e.printStackTrace();
        } catch (InternalException e) {
            e.printStackTrace();
        } catch (InvalidKeyException e) {
            e.printStackTrace();
        } catch (InvalidResponseException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        } catch (ServerException e) {
            e.printStackTrace();
        } catch (XmlParserException e) {
            e.printStackTrace();
        }
        return stream;
    }


    @Override
    public byte[] read(NetdiskOriginFile fileInfo) {

        byte[] bytes=null;
        InputStream stream=readStream(fileInfo);
        if(stream!=null){
            try {
                ByteArrayOutputStream bos=new ByteArrayOutputStream();
                byte[] b= new byte[1024];int len;
                while((len = stream.read(b))!=-1){
                    bos.write(b,0,len);
                }
                bytes = bos.toByteArray();

                    bos.close();
                }
            catch (IOException e) {
                e.printStackTrace();
            }
        }
        return bytes;

    }

    @Override
    public Boolean isFileExists(NetdiskOriginFile fileInfo) {
        MinioClient client=getMinioClient();
        try {
            StatObjectResponse statObj=client.statObject(StatObjectArgs.builder().bucket(bucket).object(fileInfo.getLocation()).build());
            if(statObj!=null&&statObj.size()>0){
                return true;
            }else{
                return false;
            }
        } catch (ErrorResponseException e) {
            e.printStackTrace();
        } catch (InsufficientDataException e) {
            e.printStackTrace();
        } catch (InternalException e) {
            e.printStackTrace();
        } catch (InvalidKeyException e) {
            e.printStackTrace();
        } catch (InvalidResponseException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        } catch (ServerException e) {
            e.printStackTrace();
        } catch (XmlParserException e) {
            e.printStackTrace();
        }
        return false;
    }
}
